package com.standard.strategy;

import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;

import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;

/**
 * 标准分片下：分表的范围策略
 * RangeShardingAlgorithm<Long> Long是因为分片键是Long型的
 */
public class CustomRangeShardingAlgorithm implements RangeShardingAlgorithm<Long> {

    /**
     * @param dataSourceNames 数据源集合
     *                      在分库时值为所有分片库的集合 databaseNames
     *                      分表时为对应分片库中所有分片表的集合 tablesNames(是表名的集合，比如product_order_0)
     *
     * @param shardingValue  分片属性，包括
     *                                  logicTableName 为逻辑表，
     *                                  columnName 分片健（字段），
     *                                  value 为从 SQL 中解析出的分片健的值
     * @return
     */
    @Override
    public Collection<String> doSharding(Collection<String> dataSourceNames, RangeShardingValue<Long> shardingValue) {

        Set<String> result = new LinkedHashSet<>();
        // 获取范围的最小值
        Long lower = shardingValue.getValueRange().lowerEndpoint();

        // 获取范围的最大值
        Long upper = shardingValue.getValueRange().upperEndpoint();

        // 循环最小值到最大值
        for(Long i = lower; i <= upper; i++){
            // 遍历所有表名，一一对比匹配
            for(String dataSourceName : dataSourceNames){
                // 对分片键取模
                String value = i % dataSourceNames.size() + "";
                if(dataSourceName.endsWith(value)){
                    result.add(dataSourceName);
                }
            }
        }
        return result;
    }
}
